<template>
  <el-form
    ref="form"
    :model="form"
    :rules="rules"
    :inline="inline"
    :label-width="labelWidth"
    :label-position="labelPosition"
    :size="size"
    :disabled="disabled"
    v-bind="$attrs"
  >
    <el-row :gutter="gutter">
      <el-col
        v-for="(item, i) in schema"
        :key="item.prop || i"
        :span="item.colSpan || Math.floor(24 / col)"
        v-show="isShown(item)"
      >
        <el-form-item
          :prop="item.prop"
          :label="item.label"
          :required="item.required"
          :rules="item.rules"
        >
          <!-- 内置类型 -->
          <el-input
            v-if="item.component === 'input'"
            v-model="form[item.prop]"
            v-bind="item.props"
            :placeholder="item.placeholder"
            clearable
          />
          <el-input
            v-else-if="item.component === 'textarea'"
            type="textarea"
            v-model="form[item.prop]"
            v-bind="item.props"
            :placeholder="item.placeholder"
          />
          <el-input-number
            v-else-if="item.component === 'number'"
            v-model="form[item.prop]"
            v-bind="item.props"
          />
          <el-select
            v-else-if="item.component === 'select'"
            v-model="form[item.prop]"
            v-bind="item.props"
            :placeholder="item.placeholder"
            clearable
          >
            <el-option
              v-for="opt in getOptions(item)"
              :key="opt.value"
              :label="opt.label"
              :value="opt.value"
              :disabled="opt.disabled"
            />
          </el-select>
          <el-radio-group
            v-else-if="item.component === 'radio'"
            v-model="form[item.prop]"
            v-bind="item.props"
          >
            <el-radio v-for="opt in getOptions(item)" :key="opt.value" :label="opt.value">
              {{ opt.label }}
            </el-radio>
          </el-radio-group>
          <el-checkbox-group
            v-else-if="item.component === 'checkbox'"
            v-model="form[item.prop]"
            v-bind="item.props"
          >
            <el-checkbox v-for="opt in getOptions(item)" :key="opt.value" :label="opt.value">
              {{ opt.label }}
            </el-checkbox>
          </el-checkbox-group>
          <el-switch
            v-else-if="item.component === 'switch'"
            v-model="form[item.prop]"
            v-bind="item.props"
          />
          <el-date-picker
            v-else-if="item.component === 'date'"
            v-model="form[item.prop]"
            :type="item.dateType || 'date'"
            :value-format="item.valueFormat || 'yyyy-MM-dd'"
            :format="item.format"
            v-bind="item.props"
          />
          <el-cascader
            v-else-if="item.component === 'cascader'"
            v-model="form[item.prop]"
            :options="getOptions(item)"
            v-bind="item.props"
          />
          <!-- 自定义插槽（字段维度） -->
          <slot
            v-else-if="item.slot"
            :name="item.slot"
            :model="form"
            :item="item"
          />
          <!-- 默认回退：展示值 -->
          <span v-else>{{ form[item.prop] }}</span>
        </el-form-item>
      </el-col>
    </el-row>
    <!-- 表单底部插槽 -->
    <slot name="actions" :form="form" :refForm="$refs.form" />
  </el-form>
</template>

<script>
export default {
  name: 'BaseForm',
  inheritAttrs: false,
  model: { prop: 'value', event: 'input' }, // v-model 支持
  props: {
    value: { type: Object, default: () => ({}) },   // v-model 绑定的表单数据
    schema: { type: Array, required: true },        // 字段配置数组
    rules: { type: Object, default: () => ({}) },   // el-form rules
    inline: { type: Boolean, default: false },
    labelWidth: { type: String, default: '100px' },
    labelPosition: { type: String, default: 'right' },
    size: { type: String, default: 'small' },
    disabled: { type: Boolean, default: false },
    col: { type: Number, default: 2 },              // 每行列数（布局）
    gutter: { type: Number, default: 16 }
  },
  data() {
    return {
      form: { ...this.value },
      optionsMap: {} // { prop: options[] }
    };
  },
  watch: {
    value: { deep: true, handler(v) { this.form = { ...v }; } },
    form: { deep: true, handler(v) { this.$emit('input', { ...v }); } }
  },
  created() {
    // 预加载异步选项（若 schema 中 options 是函数/Promise）
    this.schema.forEach(it => this.prepareOptions(it));
  },
  methods: {
    isShown(item) {
      if (typeof item.show === 'function') return !!item.show(this.form);
      if (typeof item.show === 'boolean') return item.show;
      return true;
    },
    async prepareOptions(item) {
      if (!item) return;
      const key = item.prop;
      if (!key) return;
      if (Array.isArray(item.options)) {
        this.$set(this.optionsMap, key, item.options);
      } else if (typeof item.options === 'function') {
        try {
          const res = await item.options(this.form);
          this.$set(this.optionsMap, key, res || []);
        } catch (e) {
          this.$set(this.optionsMap, key, []);
        }
      }
    },
    getOptions(item) {
      const key = item.prop;
      return (key && this.optionsMap[key]) || item.options || [];
    },
    // 对外方法
    validate() {
      return new Promise((resolve) => {
        this.$refs.form.validate(valid => resolve(valid));
      });
    },
    reset() {
      this.$refs.form.resetFields();
      // 触发一次同步
      this.$emit('input', { ...this.form });
    },
    clearValidate(props) { this.$refs.form.clearValidate(props); },
    getFormRef() { return this.$refs.form; },
    setField(prop, val) {
      this.$set(this.form, prop, val);
    },
    reloadOptions(prop) {
      const item = this.schema.find(s => s.prop === prop);
      if (item) this.prepareOptions(item);
    }
  }
};
</script>